﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using PluginSample2.BarModel;
using StockModel;

namespace PluginSample2
{
	internal class BarSourceSelector : IDisposable
	{
		#region Attributes

		private readonly BarSource _mode;
		private readonly ObservableCollection<Quotation> _source;

		#endregion

		#region Properties

		public ObservableCollection<BarSourceItem> Values { get; private set; }

		#endregion

		#region Public Methods

		public BarSourceSelector(BarSource mode, ObservableCollection<Quotation> source)
		{
			this.Values = new ObservableCollection<BarSourceItem>();

			_mode = mode;
			_source = source;

			_source.CollectionChanged += Source_CollectionChanged; // Disposed
		}

		#endregion

		#region Event Handlers

		private void Source_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
		{
			if (e.Action == NotifyCollectionChangedAction.Add)
			{
				foreach (Quotation quotation in e.NewItems)
				{
					switch (_mode)
					{
						case BarSource.LastValue:
							this.Values.Add(new BarSourceItem(quotation.Date, quotation.Value));
							break;

						case BarSource.AverageBidAsk:
							this.Values.Add(new BarSourceItem(quotation.Date, (quotation.Sellers[0].Value + quotation.Buyers[0].Value) / 2));
							break;

						case BarSource.MaxAskMinBid:
							this.Values.Add(new BarSourceItem(quotation.Date, quotation.Sellers[0].Value, quotation.Buyers[0].Value));
							break;
					}
				}
			}
			else if (e.Action == NotifyCollectionChangedAction.Reset)
			{
				this.Values.Clear();
			}
		}

		#endregion

		#region IDisposable

		protected bool Disposed { get; private set; }

		private void Dispose(bool disposing)
		{
			if (!this.Disposed)
			{
				this.InternalDispose(disposing);
			}

			this.Disposed = true;
		}

		protected virtual void InternalDispose(bool disposing)
		{
			if (disposing)
			{
				_source.CollectionChanged -= Source_CollectionChanged;
			}

			// Dispose here only unmanaged objects 
			// Don’t use managed objects here because maybe 
			// they have been finalized already
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		~BarSourceSelector()
		{
			this.Dispose(false);
		}

		#endregion
	}
}
